package com.fujimana.android.manacode.loalder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import com.fujimana.android.manacode.utils.Utils;

public class SourcesArchive extends Sources {

	private int DEFAULT_BUFFER_SIZE = 1024 * 1024;

	private Map<String, ZipEntry> entries;

	public SourcesArchive(String file) {
		super(file);
		this.entries = new HashMap<String, ZipEntry>();
	}

	public SourcesArchive(String file, String encode) {
		super(file, encode);
		this.entries = new HashMap<String, ZipEntry>();
	}

	public void read() throws IOException {
		ZipFile zf = null;

		try {
			zf = new ZipFile(getFile());

			for (Enumeration<? extends ZipEntry> e = zf.entries(); e
					.hasMoreElements();) {
				ZipEntry ze = e.nextElement();

				if (ze.isDirectory()) {
					continue;
				}

				if (filtering(ze.getName())) {
					this.entries.put(ze.getName(), ze);
				}
			}

		} finally {
			Utils.close(zf);
		}

	}

	@Override
	public byte[] getData(String entry) throws IOException {
		ZipFile zf = null;
		InputStream is = null;

		ZipEntry ze = this.entries.get(entry);

		ByteArrayOutputStream out = new ByteArrayOutputStream();

		if (ze == null) {
			return null;
		}

		try {
			zf = new ZipFile(getFile());
			is = zf.getInputStream(ze);

			byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
			int n = 0;

			while (-1 != (n = is.read(buffer))) {
				out.write(buffer, 0, n);
			}

		} finally {
			Utils.close(is);
			Utils.close(zf);
			Utils.close(out);
		}

		return out.toByteArray();
	}

	@Override
	public List<String> getEntries() {
		List<String> ret = new ArrayList<String>(entries.keySet());
		Collections.sort(ret, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.compareToIgnoreCase(o2);
			}
		});

		return Collections.unmodifiableList(ret);
	}

}